#ifndef DIAGNOSTIC1D_H
#define DIAGNOSTIC1D_H

#include "../Diagnostic/Diagnostic.h"
#include "../Input/PicParams.h"
#include "../Parallel/ParallelMPI.h"
#include "../Field/Field1D.h"
#include "../PSI/PSI1D.h"
#include "../Grid/Grid.h"
#include "../PSI/PSI1D.h"

class Collision;

class Diagnostic1D : public Diagnostic
{

public:

    Diagnostic1D(PicParams* params_, ParallelMPI* pmpi_, Grid* grid_, PhysicalField* fields_, vector<Species*>* vecSpecies_, vector<Collision*>* vecCollision_, vector<PSI*>* vecPSI_);

    virtual ~Diagnostic1D();

    //run the diag for all patches for local diags.
    virtual void run( ParallelMPI* pmpi, Grid* grid, vector<Species*>& vecSpecies, PhysicalField* fields, vector<PSI*>& vecPSI, int itime );

    //calculate velocity, temperature, total particle energy for each species, total electric field energy
    void cal_VT(ParallelMPI* pmpi, vector<Species*>& vecSpecies, PhysicalField* fields, int itime);

    //init vedf
    void init_vedf();

    //calculate velocity/energy distribution function
    void cal_vedf(ParallelMPI* pmpi, vector<Species*>& vecSpecies, int itime);

    //calculate total energy(particles and electric field)
    //void calTotalEnergy(ParallelMPI* pmpi, vector<Species*>& vecSpecies, PhysicalField* fields, int itime){};

    //parameters for calculate energy distribution of incident ions on the target
    int n_energy;
    double energy_max;

    Field1D<double> *ptclNum1D;

    vector<int> particle_number;                        //particle_number[ispec]
    vector<double> total_particle_energy;               //total_paritcle_energy[ispec]
    double total_electric_field_energy;

	vector<double> particle_flux_left;                  //particle_flux_left[ispec]
    vector<double> particle_flux_right;                 //particle_flux_right[ispec]
	vector<double> heat_flux_left;                      //heat_flux_left[ispec]
    vector<double> heat_flux_right;                     //heat_flux_right[ispec]

    vector< vector<double> > angle_distribution_left;   //angle_distribution_left[ispec][i_angle]
    vector< vector<double> > angle_distribution_right;  //angle_distribution_right[ispec][i_angle]
    vector< vector<double> > energy_distribution_left;  //energy_distribution_left[ispec][i_energy]
    vector< vector<double> > energy_distribution_right; //energy_distribution_right[ispec][i_energy]

    //psi_rate has different meaning for different psi process, like physical sputtering rate, reflection rate
    vector<double> psi_rate_left;                            //psi_rate_left[i_psi]
    vector<double> psi_rate_right;                           //psi_rate_right[i_psi]

    //intermediate variable, not ouput, for psi rate calculation
    vector<int> psi_species1;                                 //psi_species1[i_psi]

    //radiative_energy_collision[iCollision][iBin]
    vector< vector<double> > radiative_energy_collision;

    //sigma is surface charge density, used to determine the electric field at the target boudary
    vector<double> sigma_left;                          //sigma_left[ispec]
    vector<double> sigma_right;                         //sigma_right[ispec]

    //vdf: velocity distribution function
    //edf: energy distribution function
    //vdf[n_position][n_species][n_velocity]
    Field3D<double> vdf_x;
    Field3D<double> vdf_y;
    Field3D<double> vdf_z;
    Field3D<double> vdf_parallel_to_B;
    Field3D<double> vdf_perpendicular_to_B;    //in the xy plane
    Field3D<double> edf;

    //vedf_temp: temporary field for gathering field
    Field3D<double> vedf_temp;

    vector<int> vdf_cell_local;
    vector<int> vdf_position_index_global;

    Field2D<double> vdf_velocity_array;
    Field2D<double> edf_energy_array;
    vector<double> vdf_dv;       //velocity interval
    vector<double> edf_de;       //energy interval

    //alhpa is the angle of B to the target
    //sin_alhpa, cos_alhpa is used to calculate velocity perpendicular and parallel to B
    double sin_alpha;
    double cos_alpha;


protected :

    double dx;
    //Inverse of the spatial step 1/dx
    double dx_inv_;
    //parameters to project macroscopic velocity and temperature
    int index_domain_begin;

};

#endif
